/** 工具
 * @Name index;
 * @Author FiveXu
 * @Description index
 * @Date 2021-06-28 17:37
 */

import { useSetInterval } from '@/base/hooks'

/** 颜色转化为 rgba 格式
 * @param {string} colorText 颜色 #xxx rgb(x,x,x) 格式
 * @param {number} alpha 透明度 0-1 自然数
 */
export const colorRgb = (colorText: string, alpha = 1): string => {
  let color = colorText.toUpperCase()
  if (/^RGBA/.test(color)) {
    const a = colorText.split(',')
    let b = ''
    a.forEach((item: string, index: number) => {
      if (index < a.length - 1) b += `${item},`
    })
    return `${b} ${alpha})`.toLowerCase()
  }
  if (/^RGB/.test(color)) {
    color = color.replace(/^RGB/, 'rgba')
    color = color.replace(/\)$/, `, ${alpha})`)
    return color.toLowerCase()
  }
  const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
  if (reg.test(color)) {
    if (color.length === 4) {
      let colorNew = '#'
      for (let i = 1; i < 4; i += 1) {
        colorNew += color.slice(i, i + 1).concat(color.slice(i, i + 1))
      }
      color = colorNew
    }
    const colorChange = []
    for (let i = 1; i < 7; i += 2) {
      colorChange.push(parseInt('0x' + color.slice(i, i + 2)))
    }
    return `rgba(${colorChange.join(',')},${alpha})`.toLowerCase()
  } else {
    return color.toLowerCase()
  }
}

/**
 * RGBA格式转十六进制
 * @param color
 */
export const rgbaToHex = (color: string): string => {
  const toHex = (col: number) => ('0' + col.toString(16)).slice(-2)
  const values = color.toLowerCase()
    .replace(/rgba?\(/, '')
    .replace(/\)/, '')
    .replace(/[\s+]/g, '')
    .split(',')
  const a = parseFloat(values[3] ?? 1)
  const floorColor = (num: number) => Math.floor(a * parseInt(values[num]) + (1 - a) * 255)
  return `#${toHex(floorColor(0))}${toHex(floorColor(1))}${toHex(floorColor(2))}`
}

/** 颜色格式化为 rgb 数字数组
 * @param color 任意color值
 */
export const getColorToArray = (color: string): number[] => {
  color = colorRgb(color)
  const colorStr = color.replace(/rgba|\(|\)|, 1/g, '')
  return colorStr.split(',').map((item: string) => Number(item))
}

/** 随机字符
 * @param num 随机字符个数
 */
const randomWord = (num: number): string => {
  let randomText = ''
  const arr = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'.split('')
  Array.from(new Array(num)).forEach((): void => {
    randomText += arr[Math.floor((arr.length - 1) * Math.random())]
  })
  return randomText
}
// 随机ID
export const randomId = (num = 10, time = true): string => {
  const date = time ? `-${new Date().getTime()}` : ''
  return `fx-${randomWord(num)}${date}`
}
/** 给dom添加class
 * @param dom
 * @param className
 */
export const addClassName = (dom: HTMLElement, className: string): void => {
  const classNameArray: string[] = dom.className.split(' ').filter((item: string) => !!item.trim())
  const isClassName = classNameArray.includes(className)
  if (!isClassName) dom.className += `${classNameArray.length ? ' ' : ''}${className}`
}
/** 移除dom上的class
 * @param dom
 * @param className
 */
export const removeClassName = (dom: HTMLElement, className: string | string[]): void => {
  const classNameArr = [className].flat(Infinity) as string[]
  classNameArr.forEach((item: string) => {
    dom.className = dom.className.replace(new RegExp(item, 'g'), '').trim()
  })
}

/** 骇客技术添加css样式
 * @param style style名
 */
export const prefixStyle = (style: string): string | number => {
  const vendor = (() => {
    const transformName = {
      webkit: 'webkitTransform',
      Moz: 'MozTransform',
      O: 'OTransform',
      ms: 'msTransform',
      standard: 'transform'
    }
    for (const key in transformName) {
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      // @ts-ignore
      const domKey = document.createElement('div').style[transformName[key]]
      if (domKey !== undefined) return key
    }
    return false
  })()
  if (!vendor) return ''
  if (vendor === 'standard') return style
  return vendor + style.charAt(0).toUpperCase() + style.substr(1)
}

/** 时间格式化
 * @param {String} type 转时间方式  YYYY=年2019 YY=年19 MM=月 DD=天 hh:时 mm:分 ss:秒
 * @param {Date} val
 * @return {String} 格式换时间
 * */
export const dateFormat = (type: 'year' | 'month' | 'day' | string, val?: Date | string): string => {
  let date: Date = new Date()
  if (val) date = new Date(val)
  const YYYY = String(date.getFullYear())
  const YY = String(date.getFullYear()).substr(2)
  const m = date.getMonth() + 1
  const MM = m > 9 ? `${m}` : '0' + m
  const d = date.getDate()
  const DD = d > 9 ? `${d}` : '0' + d
  const h = date.getHours()
  const hh = h > 9 ? `${h}` : '0' + h
  const $m = date.getMinutes()
  const mm = $m > 9 ? `${$m}` : '0' + $m
  const s = date.getSeconds()
  const ss = s > 9 ? `${s}` : '0' + s
  const obj: { [key: string]: string } = {
    YYYY,
    YY,
    MM,
    DD,
    hh,
    mm,
    ss
  }
  if (type === 'year') return YYYY
  if (type === 'month') return `${YYYY}-${MM}`
  if (type === 'day') return `${YYYY}-${MM}-${DD}`
  return type.replace(/(YYYY)|(YY)|(MM)|(DD)|(hh)|(mm)|(ss)/g, (key: string) => obj[key])
}

/** 创建单一连续数字数组
 * @param num 数组长度
 * @param from 数组起始数
 */
export const createList = (num: number, from = 0): number[] => {
  const arr = []
  for (let i = 0; i < num; i++) {
    arr.push(from ? i + from : i)
  }
  return arr
}

/** 选中文字
 * @param dom
 * @param start
 * @param end
 */
export const selectTextRange = (dom: HTMLElement, start: number, end: number): void => {
  if (!dom) return
  const range = document.createRange()
  range.setStart(dom.firstChild as Node, start)
  range.setEnd(dom.firstChild as Node, end)
  const selection = window.getSelection()
  if (!selection) return
  selection.removeAllRanges()
  selection.addRange(range)
}

/** rgb颜色转为数组
 * @param color
 */
export const getRGBToArray = (color: string): number[] => {
  color = colorRgb(color, 1)
  if (!(/^rgba/.test(color))) return []
  color = color.replace(/rgba\(|\)/g, '')
  color = color.replace(' ,1', '')
  return color.split(',').map((item: string) => Number(item))
}

/** 阻止滚动
 * @param disable 是否需要阻止
 */
export const disableAllowScroll = (disable: boolean): void => {
  if (disable) {
    addClassName(document.body, 'fx-disable-allow-scroll')
  } else {
    removeClassName(document.body, 'fx-disable-allow-scroll')
  }
}

/** 获取每月天数
 * @param year 获取的年份
 * @param month 获取的月份
 */
export const getMonthDay = (year = new Date().getFullYear(), month = new Date().getMonth()): number => {
  return new Date(year, month + 1, 0).getDate()
}

/** 滚动到指定位置函数
 * @param scrollToNum 滚动位置
 * @param dom HTML DOM
 */
export const scrollYAnimation = (scrollToNum: number, dom = document.body): void => {
  let scrollTop = dom.scrollTop
  if (scrollToNum === scrollTop) return
  const runningCount = 5
  const scrollNum = Math.abs(scrollTop - scrollToNum) / runningCount
  const clear = useSetInterval(() => {
    if (scrollTop > scrollToNum) {
      scrollTop -= scrollNum
      if (scrollTop <= scrollToNum) {
        clear()
        scrollTop = scrollToNum
      }
    } else {
      scrollTop += scrollNum
      if (scrollTop >= scrollToNum) {
        clear()
        scrollTop = scrollToNum
      }
    }
    dom.scrollTo(0, scrollTop)
  }, 20)
}
